package com.mingqijia.gassafety.job.job.message;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mingqijia.gassafety.db.entity.BusinessNotice;
import com.mingqijia.gassafety.db.entity.Dtu;
import com.mingqijia.gassafety.db.entity.PushMsg;
import com.mingqijia.gassafety.db.mapper.BusinessNoticeMapper;
import com.mingqijia.gassafety.db.mapper.DtuMapper;
import com.mingqijia.gassafety.db.mapper.PushMsgMapper;
import com.mingqijia.gassafety.job.dto.cms.CmsInfoReqDTO;
import com.mingqijia.gassafety.job.service.CompanyService;
import com.mingqijia.gassafety.shared.constant.Constants;
import com.mingqijia.gassafety.shared.constant.PushMsgEnum;
import com.mingqijia.gassafety.shared.dto.cms.CmsInfoResDTO;
import com.mingqijia.gassafety.shared.utils.RedisCacheExt;
import com.mingqijia.gassafety.shared.utils.message.AppMessageService;
import com.mingqijia.gassafety.shared.utils.message.CmsMessageService;
import com.mingqijia.gassafety.shared.utils.message.SendMessageService;
import com.mingqijia.gassafety.shared.vcc.VccAuthoritiesProvider;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.xxl.job.core.log.XxlJobLogger;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhangfei
 * @version 1.0.0
 * @ClassName MessageReceiptCompensateJob.java
 * @Description 推送消息
 * @createTime 2022年30月31日
 */
@Component
@Slf4j
public class MessagePushJob {
    @Autowired
    RedisCacheExt redisUtil;
    @Autowired
    AppMessageService appMessageService;
    @Autowired
    SendMessageService sendMessageService;

    @Autowired
    CmsMessageService cmsMessageService;
    @Autowired
    VccAuthoritiesProvider provider;
    @Autowired
    PushMsgMapper pushMsgMapper;
    @Autowired
    CompanyService companyService;

    @Autowired
    BusinessNoticeMapper noticeMapper;

    @Autowired
    DtuMapper dtuMapper;

    private static final Integer sendTime = 3;

    /**
     * 发送短信和app消息  0 0/1 * * * ?
     */
    @XxlJob("messagePush")
//    @Scheduled(cron = "${gassafety.job.messagePush}")
    public ReturnT<String> messagePush(String params) {
        XxlJobLogger.log("XXLJOB-messagePush start..." );
        log.info("messagePush--start--------");
        //防重复锁
        String key = Constants.MESSAGE_PUSH;
        try {
            Boolean acquire = redisUtil.setIfAbsent(key, String.valueOf(System.currentTimeMillis()), Constants.TIME_OUT);//15分钟超时
            if (acquire) {
                try {
                    List<PushMsg> pushMsgList = pushMsgMapper.selectMessageList(sendTime);
                    log.info("messagePush-pushMsgList:{}", JSONObject.toJSONString(pushMsgList));
                    if (CollectionUtils.isEmpty(pushMsgList))  return ReturnT.SUCCESS;;
                    List<PushMsg> appPushs = pushMsgList.stream().filter(pushMsg -> {
                        return pushMsg.getPushTimes() < 3 && pushMsg.getPushTimes() > 0;
                    }).collect(Collectors.toList());
                    log.info("messagePush-appPushs:{}", JSONObject.toJSONString(appPushs));
                    List<PushMsg> sendPushs = pushMsgList.stream().filter(pushMsg -> {
                        return pushMsg.getSendTimes() < 3 && pushMsg.getSendTimes() > 0;
                    }).collect(Collectors.toList());
                    log.info("messagePush-sendPushs:{}", JSONObject.toJSONString(sendPushs));
                    if (!CollectionUtils.isEmpty(appPushs)) {
                        Map<Integer, List<PushMsg>> collect = appPushs.stream()
                                .collect(Collectors.groupingBy(PushMsg::getPushType, Collectors.toList()));
                        collect.forEach((integer, pushMsgs) -> {
                            Map<String, List<PushMsg>> collectSpId = pushMsgs.stream()
                                    .collect(Collectors.groupingBy(PushMsg::getSpId, Collectors.toList()));
                            try {
                                collectSpId.forEach((s, pushMsgsSpId) -> {
                                            List<String> memberIds = pushMsgsSpId.stream().map(PushMsg::getMemberId).collect(Collectors.toList());
                                            if (!CollectionUtils.isEmpty(memberIds)) {
                                                //发消息
                                                QueryWrapper<BusinessNotice> query = new QueryWrapper<>();
                                                query.lambda().or().eq(BusinessNotice::getIsDeleted, 0)
                                                        .eq(BusinessNotice::getSpId, s)
                                                        .eq(BusinessNotice::getParamCode, "cm_service_hot_line");
                                                List<BusinessNotice> r = noticeMapper.selectList(query);
                                                String phone = "";
                                                if (!CollectionUtil.isEmpty(r)) {
                                                    phone = r.get(0).getParamValue();
                                                    appMessageService.sendSms(appMessageService
                                                            .getRequestParam(memberIds.toArray(new String[memberIds.size()]),
                                                                    String.format(PushMsgEnum.getText(integer), phone), PushMsgEnum.getTitle(integer)));
                                                }


                                            }
                                        }
                                );
                            } catch (Exception e) {
                                log.info("collectSpId-error:{}",e);
                            }
                        });
                        List<Long> ids = appPushs.stream().map(PushMsg::getId)
                                .collect(Collectors.toList());
                        if (!CollectionUtils.isEmpty(ids))pushMsgMapper.updateByIds(ids, 0);
                    }

                    if (!CollectionUtils.isEmpty(sendPushs)) {
                        for (PushMsg sendPush : sendPushs) {
                            QueryWrapper<Dtu> query = new QueryWrapper<>();
                            query.lambda().or().eq(Dtu::getIsDeleted, 0)
                                    .eq(Dtu::getSpId, sendPush.getSpId())
                                    .eq(Dtu::getIMEI, sendPush.getDeviceId());
                            List<Dtu> dtus = dtuMapper.selectList(query);
                            String orgCode = companyService.getOrgCode(sendPush.getSpId(),
                                    CollectionUtils.isEmpty(dtus)?null:dtus.get(0).getConsumerId()+"");
                            String phone = provider.getOrgInfoTel(orgCode);
                            Map<String, Object> param = new HashMap<>();
                            param.put("phone", phone);
                            sendMessageService.sendSms(sendMessageService
                                            .getRequestParam(sendPush.getPhone()
                                                    , PushMsgEnum.getCode(sendPush.getPushType()), orgCode
                                                    , param, "sms", null, null, null,Constants.ZJ_EQUIPMENT_FROM)
                                    , "");

                        }
                        List<Long> ids = sendPushs.stream().map(PushMsg::getId)
                                .collect(Collectors.toList());
                        if (!CollectionUtils.isEmpty(ids))
                        pushMsgMapper.updateByIds(ids, 1);
                    }
                    //站内信发送
                    sendCmsMsg(pushMsgList);
                } catch (Exception e) {
                    log.info("messagePush-error:{}", e);
                } finally {
                    redisUtil.del(key);
                }
            }
        } catch (Exception e) {
            log.info("messagePush-error:{}", e);
        }
        log.info("messagePush--end--------");
        XxlJobLogger.log("XXLJOB-messagePush end..." );
        return ReturnT.SUCCESS;
    }

    private void sendCmsMsg(List<PushMsg> pushMsgList) {
        //获取站内推送次数0<x<3
        List<PushMsg> sendCmsPushList = getCmsPushList(pushMsgList);
        //推送站内信
        beginToSendCmsMsg(sendCmsPushList);
        //更新站内信推送次数w
        List<Long> collect = sendCmsPushList.stream().map(PushMsg::getId).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(sendCmsPushList)&&!CollectionUtils.isEmpty(collect)) pushMsgMapper.updateByIds(collect, 2);
    }

    private void beginToSendCmsMsg(List<PushMsg> sendCmsPushList) {
        //站内推次数不足3，继续推送
        if (ObjectUtil.isNotEmpty(sendCmsPushList)) {
            sendCmsPushList.stream().forEach(item -> {
                String title = PushMsgEnum.getTitle(item.getPushType());
                //站内信参数封装
                cn.hutool.json.JSONObject cmsReqParams = cmsMessageService.getCmsJSONParams(item.getPushText(), title, Integer.parseInt(item.getMemberId()));
                //站内信发送，不论成败，只记录发送次数
                cmsMessageService.sendCmsMsg(cmsReqParams);
            });
        }
    }

    private List<PushMsg> getCmsPushList(List<PushMsg> pushMsgList) {
        List<PushMsg> sendCmsPushList = pushMsgList.stream().filter(pushMsg -> {
            return pushMsg.getSendCmsTimes() < 3 && pushMsg.getSendCmsTimes() > 0;
        }).collect(Collectors.toList());
        log.info("messagePush-sendCmsPushList:{}", JSONObject.toJSONString(sendCmsPushList));
        return sendCmsPushList;
    }
}
